﻿using System;

using Microsoft.Practices.ServiceLocation;

namespace Fuse8.DomainFramework.Common.Locator
{
    /// <summary>
    /// Extend <see cref="IServiceLocator" /> for support registration default services
    /// </summary>
    public interface IServiceLocatorEx : IServiceLocator
    {
        /// <summary>
        /// Register instance of service in IoC
        /// </summary>
        /// <typeparam name="TService"></typeparam>
        /// <param name="service"></param>
        void Register<TService>(TService service);

        /// <summary>
        /// Register instance of service in IoC with key
        /// </summary>
        /// <typeparam name="TService"></typeparam>
        /// <param name="key"> </param>
        /// <param name="service"></param>
        void Register<TService>(string key, TService service);

        /// <summary>
        /// Register type of service in IoC
        /// </summary>
        /// <param name="typeTo"></param>
        /// <param name="serviceType"></param>
        void Register(Type typeTo, Type serviceType);

        /// <summary>
        /// Register type of service in IoC with key
        /// </summary>
        /// <param name="typeTo"></param>
        /// <param name="key"> </param>
        /// <param name="serviceType"></param>
        void Register(Type typeTo, Type serviceType, string key);

        /// <summary>
        /// Check if some instance of TService is registered in IoC
        /// </summary>
        /// <typeparam name="TService">Type of instance</typeparam>
        /// <returns>True if registered, false if not</returns>
        bool IsRegistered<TService>();

        /// <summary>
        /// Check if some instance of TService is registered in IoC
        /// </summary>
        /// <typeparam name="TService">Type of instance</typeparam>
        /// <returns>True if registered, false if not</returns>
        bool IsRegistered<TService>(string key);

        /// <summary>
        /// Check if some type is registered in IoC
        /// </summary>
        /// <param name="serviceType">Type of registration</param>
        /// <returns>True if registered, false if not</returns>
        bool IsRegistered(Type serviceType);

        /// <summary>
        /// Check if some type is registered in IoC
        /// </summary>
        /// <param name="serviceType">Type of registration</param>
        /// <param name="key"> </param>
        /// <returns>True if registered, false if not</returns>
        bool IsRegistered(Type serviceType, string key);

        /// <summary>
        /// Set default registration to IoC
        /// </summary>
        /// <typeparam name="TService">Type of instance</typeparam>
        /// <param name="service">Instance of service to register as default</param>
        void SetDefaultService<TService>(TService service);

        /// <summary>
        /// Set default registration to IoC
        /// </summary>
        /// <param name="serviceType">Type of registration</param>
        void SetDefaultService(Type serviceType);

        /// <summary>
        /// Get default registration
        /// </summary>
        /// <typeparam name="TService">Type of instance</typeparam>
        /// <returns>Registerd instance</returns>
        TService GetDefaultService<TService>();

        /// <summary>
        /// Get default registration
        /// </summary>
        /// <param name="serviceType">Type of registration</param>
        /// <returns>Registerd instance</returns>
        object GetDefaultService(Type serviceType);

        /// <summary>
        /// Check if an instance of TService is registered in IoC as default service
        /// </summary>
        /// <typeparam name="TService">Type of instance</typeparam>
        /// <returns>True if registered, false if not</returns>
        bool IsDefaultServiceRegistered<TService>();

        /// <summary>
        /// Check if a type is registered in IoC as a type for default service
        /// </summary>
        /// <param name="serviceType">Type of registration</param>
        /// <returns>True if registered, false if not</returns>
        bool IsDefaultServiceRegistered(Type serviceType);
    }
}
